# -*- coding: utf-8 -*-

""" This file stores all the types and variable definitions about ports.
"""
from .ir_value import IValue
from .ir_type import IType


# -- Port types --
class ITypePort(IType):
    def __init__(self, type_name: str):
        super(ITypePort, self).__init__(type_name, -1)


class ITypePortBase(ITypePort):
    def __init__(self, type_name: str, managed_type: IType):
        super(ITypePortBase, self).__init__(type_name)
        self.managed_type = managed_type
        self.generic = {}


class ITypePortIn(ITypePortBase):
    def __init__(self, managed_type: IType, max_size: int = -1):
        super(ITypePortIn, self).__init__('PortIn', managed_type)
        self.max_size = max_size
        self.generic['T'] = managed_type

    def __str__(self):
        return 'PortIn<{}>'.format(self.managed_type)


class ITypePortInDirect(ITypePortBase):
    def __init__(self, managed_type: IType):
        super(ITypePortInDirect, self).__init__('PortInDirect', managed_type)
        self.generic['T'] = managed_type

    def __str__(self):
        return 'PortInDirect<{}>'.format(self.managed_type)


class ITypePortOut(ITypePortBase):
    def __init__(self, managed_type: IType):
        super(ITypePortOut, self).__init__('PortOut', managed_type)
        self.generic['T'] = managed_type

    def __str__(self):
        return 'PortOut<{}>'.format(self.managed_type)


class ITypeLane(IType):
    def __init__(self, name: str):
        super(ITypeLane, self).__init__('Lane', -1)
        self.name = name

    def __str__(self):
        return self.name


class ITypeLanePort(ITypePort):
    def __init__(self, name: str, type_name: str):
        super(ITypeLanePort, self).__init__(type_name)
        self.name = name
        self.ports = {}

    def __str__(self):
        return self.name


class ITypeLanePortSender(ITypeLanePort):
    def __init__(self, lane_name: str):
        super(ITypeLanePortSender, self).__init__(lane_name + 'Sender', 'LanePortSender')


class ITypeLanePortReceiver(ITypeLanePort):
    def __init__(self, lane_name: str):
        super(ITypeLanePortReceiver, self).__init__(lane_name + 'Receiver', 'LanePortReceiver')
        self.order = []


class ITypeChannel(IType):
    def __init__(self, name: str):
        super(ITypeChannel, self).__init__('Channel', -1)
        self.name = name

    def __str__(self):
        return self.name


class ITypeChannelPort(ITypePort):
    def __init__(self, name: str, type_name: str):
        super(ITypeChannelPort, self).__init__(type_name)
        self.name = name
        self.ports = {}

    def __str__(self):
        return self.name


class ITypeChannelPortSender(ITypeChannelPort):
    def __init__(self, channel_name: str):
        super(ITypeChannelPortSender, self).__init__(channel_name + 'Sender', 'ChannelPortSender')


class ITypeChannelPortReceiver(ITypeChannelPort):
    def __init__(self, channel_name: str):
        super(ITypeChannelPortReceiver, self).__init__(channel_name + 'Receiver', 'ChannelPortReceiver')
